package com.filldream.fastboot.core.manager;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.filldream.fastboot.common.entity.ErrorCode;
import com.filldream.fastboot.common.entity.LoginEx;
import com.filldream.fastboot.common.entity.R;
import com.filldream.fastboot.common.util.JsonUtil;
import com.filldream.fastboot.common.util.RequestContext;
import com.filldream.fastboot.core.cache.CacheMap;
import com.filldream.fastboot.core.cache.CacheObj;
import com.filldream.fastboot.core.cache.CacheUtil;
import lombok.extern.slf4j.Slf4j;
import java.util.Date;

/**
 * @author RickSun
 * @Description 登陆错误次数安全验证
 **/
@Slf4j
public class LoginSafeUtil {

    //TODO 此处没有做saas化处理，若做saas话就得区分link_id,可能登录页需要选择门店

    /**
     * @author RickSun
     * @Description 校验记录
     **/
    public static R<LoginEx> check(String account){

        LoginEx exConfig = new LoginEx();
        if(exConfig.initExConfig()){
            return R.successd(exConfig);
        }

        CacheObj<LoginEx> cache = CacheUtil.getCache(CacheMap.LOGIN_SAFE, LoginEx.class, account);
        LoginEx loginEx = cache.getData();

        //没有缓存信息,说明不需要验证码
        if( loginEx == null ){
            return R.successd(new LoginEx());
        }

        loginEx.initNextIsNeed();
        loginEx.initNowIsNeed();
        loginEx.initNextIsNeedWhenError();
        Date canLoginTime = loginEx.getCanLoginTime();

        log.info("校验登录:" + JsonUtil.toJson(loginEx));

        //ip是否IP封禁
        if( loginEx.getIsNormalEx() == false && loginEx.getIpLimitTime() > 0 ){
            return R.diy(ErrorCode.BASE_ERR.reMsg("当前IP已被封禁"),loginEx).put("need",true);
        }

        //冻结中直接返回
        if( canLoginTime.getTime() > System.currentTimeMillis() ){
            long between =  DateUtil.between(new Date(),canLoginTime, DateUnit.SECOND,false);
            String msg = "请" + (between < 60 ? between + "秒" : between / 60 + "分") + "后重试";
            return R.diy(ErrorCode.BASE_ERR.reMsg(msg),loginEx).put("need",true);
        }

        return R.successd(loginEx).put("need",loginEx.getNextIsNeed());

    }

    /**
     * @author RickSun
     * @Description 增加错误次数
     **/
    public static R<LoginEx> limit(LoginEx loginEx, String account){

        LoginEx exConfig = new LoginEx();
        if(exConfig.initExConfig()){
            return R.successd(exConfig);
        }
        Integer maxLimitTime = loginEx.maxLimitTime();
        if( maxLimitTime < 0 ){
            maxLimitTime = 60 * 60 * 24 * 30;
        }

        if(loginEx == null){ loginEx = new LoginEx();}
        loginEx.setIp( RequestContext.getIp() );
        loginEx.setErrCount(loginEx.getErrCount() + 1);
        loginEx.setLastErrTime(new Date());
        loginEx.initType();
        loginEx.initCanLoginTime();
        loginEx.initType();
        if( loginEx.getNextIsNeedWhenError() ){
            loginEx.setNextIsNeed(true);
        }

        if( loginEx.getIsNormalEx() == false && loginEx.getIpLimitTime() > 0){
            //封禁IP
            String ip = loginEx.getIp();
            log.info("封禁IP:{}",ip);
            CacheUtil.overCacheObj(CacheMap.LOGIN_SAFE.getKeyName(ip), loginEx,loginEx.getIpLimitTime() + 100);
            CacheUtil.overCacheObj(CacheMap.LOGIN_SAFE.getKeyName(account),loginEx,maxLimitTime + 100);
            return check(account);
        }else{
            CacheUtil.overCacheObj(CacheMap.LOGIN_SAFE.getKeyName(account),loginEx,maxLimitTime + 100);
        }
        log.info("封禁账号:{},封禁次数:{}",account,loginEx.getErrCount());

        return check(account);
    }

    /**
     * @author RickSun
     * @Description 清空次数
     **/
    public static void unseal(String account){
        String ip = RequestContext.getIp();
        String keyName = CacheMap.LOGIN_SAFE.getKeyName(ip);
        String keyName2 = CacheMap.LOGIN_SAFE.getKeyName(account);
        CacheUtil.delKeys(keyName,keyName2);
    }

}
